package com.yourenbang.lingyun.transaction.web.service.impl.yxy;

import com.alibaba.fastjson.JSONObject;
import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.Constant;
import com.yourenbang.lingyun.constants.enums.ChannelIdEnums;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.constants.enums.ShareLevelRateTypeEnums;
import com.yourenbang.lingyun.constants.enums.mq.MqEnum;
import com.yourenbang.lingyun.constants.enums.table.MerchantEnum;
import com.yourenbang.lingyun.constants.enums.table.PayTransactionEnum;
import com.yourenbang.lingyun.core.base.bean.SpringContextUtils;
import com.yourenbang.lingyun.core.message.Result;
import com.yourenbang.lingyun.core.util.BizAssertUtils;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.StringUtils;
import com.yourenbang.lingyun.core.util.date.LocalDateUtils;
import com.yourenbang.lingyun.core.util.http.HttpClientUtil;
import com.yourenbang.lingyun.core.util.redis.KlksRedisUtils;
import com.yourenbang.lingyun.domain.*;
import com.yourenbang.lingyun.mapper.Merchant21Mapper;
import com.yourenbang.lingyun.mapper.MerchantPledgeCashPolicyMapper;
import com.yourenbang.lingyun.mapper.PayTransactionIndexMapper;
import com.yourenbang.lingyun.mapper.Terminal21Mapper;
import com.yourenbang.lingyun.transaction.constant.LklTransTypeEnum;
import com.yourenbang.lingyun.transaction.mapper.TransactionPayTransactionMapper;
import com.yourenbang.lingyun.transaction.util.PayTransactionUtil;
import com.yourenbang.lingyun.transaction.web.domain.dto.pay.MqPayTransationDTO;
import com.yourenbang.lingyun.transaction.web.service.CommonService;
import com.yourenbang.lingyun.transaction.web.service.impl.pay.transaction.PayTransactionConfig;
import com.yourenbang.lingyun.transaction.web.service.pay.PayTransactionOrderService;
import com.yourenbang.lingyun.transaction.web.service.pay.klks.PayEposService;
import com.yourenbang.lingyun.transaction.web.service.pay.klks.PayP35Service;
import com.yourenbang.lingyun.transaction.web.service.yxy.YxyTradeService;
import com.yourenbang.mcenter.api.model.dto.MqSendMessage;
import com.yourenbang.mcenter.api.service.McenterMqService;
import com.yourenbang.merchant.api.model.dto.CheckActiveRewardYxyDTO;
import com.yourenbang.merchant.api.model.dto.CreateRewardYxyDTO;
import com.yourenbang.merchant.api.model.dto.SaveMerchantDTO;
import com.yourenbang.merchant.api.model.dto.YsPaySaveMerchantDTO;
import com.yourenbang.merchant.api.service.yxy.MerchantYxyApiService;
import com.yourenbang.merchant.api.service.yxy.MerchantYxyRewardApiService;
import com.yourenbang.terminal.api.model.dto.RpcYxyCallbackBindDTO;
import com.yourenbang.terminal.api.model.dto.RpcYxyTerminalBindDTO;
import com.yourenbang.terminal.api.service.RpcYxyTerminalService;
import com.yourenbang.transaction.api.model.vo.pay.PayTransaction;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Description
 * @Date 2021/4/26 15:13
 * @Created by Jason
 */
@Slf4j
@Service
public class YxyTradeServiceImpl implements YxyTradeService {

    private static final BigDecimal REACH_AMT = new BigDecimal("600000");
    private static final BigDecimal HIERARCHY_REWARD_NEW_POLICY = new BigDecimal("25");
    private static final BigDecimal REWARD_AMT = new BigDecimal("100");
    private static final String SFT_SUCCESS_CODE = "00";
    private static final String M40_DISCOUNT_RATE_PUSH = "您已成功开通优惠费率，优惠期间享受单笔≤300元，单月≤3万元的零费率优惠政策";

    @Autowired
    private MerchantYxyApiService merchantYxyApiService;
    @Autowired
    private PayTransactionOrderService payTransactionOrderService;
    @Autowired
    private MerchantYxyRewardApiService merchantYxyRewardApiService;
    @Autowired
    private McenterMqService mcenterMqService;
    @Autowired
    private PayTransactionIndexMapper payTransactionIndexMapper;
    @Autowired
    private TransactionPayTransactionMapper transactionPayTransactionMapper;
    @Autowired
    private Merchant21Mapper merchant21Mapper;
    @Autowired
    private RpcYxyTerminalService rpcYxyTerminalService;
    @Autowired
    private PayEposService payEposService;
    @Autowired
    KlksRedisUtils klksRedisUtils;

    @Autowired
    PayP35Service payP35Service;

    @Autowired
    private CommonService commonService;

    @Resource
    Terminal21Mapper terminal21Mapper;
    @Resource
    MerchantPledgeCashPolicyMapper merchantPledgeCashPolicyMapper;

    @Override
    @Transactional
    public PayTransaction saveTrade(PayTransaction payTransaction) {
        PayTransactionIndexExample payTransactionIndexExample = new PayTransactionIndexExample();
        payTransactionIndexExample.createCriteria()
                .andOrderNoEqualTo(payTransaction.getOrderNo())
                .andPlatNoEqualTo(PlatNoEnums.YXY.getCode())
                .andChannelIdEqualTo(payTransaction.getChannelId());
        List<PayTransactionIndex> payTransactionIndices = payTransactionIndexMapper.selectByExample(payTransactionIndexExample);
        if (payTransactionIndices.isEmpty()) {
            payTransactionIndexMapper.insertSelective(payTransactionOrderService.getPayTransactionIndexByPayTransaction(payTransaction));
        } else {
            //推送交易状态成功且库中交易不为成功
            if (PayTransactionEnum.TransactionStatus.STATUS_10.isEquals(payTransaction.getStatus())
                    && !payTransaction.getStatus().equals(payTransactionIndices.get(0).getStatus())) {
                KLog.info("重复推送交易,状态不一致,更新:{}", payTransaction.toJSON());
                PayTransactionIndex payTransactionIndexByPayTransaction = payTransactionOrderService.getPayTransactionIndexByPayTransaction(payTransaction);
                payTransactionIndexByPayTransaction.setPayTransactionIndexId(payTransactionIndices.get(0).getPayTransactionIndexId());
                int i = payTransactionIndexMapper.updateByPrimaryKeySelective(payTransactionIndexByPayTransaction);
                BizAssertUtils.assertOne(i, "更新交易失败");
            } else {
                KLog.info("重复推送交易,不处理:{}", payTransaction.toJSON());
            }
        }
        PayTransaction byOrderNo = transactionPayTransactionMapper
                .getByOrderNo(PayTransactionConfig.getTransTableIndex(payTransaction.getUserBaseId()), payTransaction.getOrderNo());

        if (Objects.isNull(byOrderNo)) {
            transactionPayTransactionMapper.insert(PayTransactionConfig.getTransTableIndex(payTransaction.getUserBaseId()), payTransaction);
        } else {
            PayTransaction oldOrder = transactionPayTransactionMapper.getByOrderNo(PayTransactionConfig.getTransTableIndex(payTransaction.getUserBaseId()),
                    payTransaction.getOrderNo());
            //如果第一次推送是成功订单,第二次重复推送不处理
            if (!PayTransactionEnum.TransactionStatus.STATUS_10.isEquals(oldOrder.getStatus())) {
                payTransaction.setPayTransactionId(oldOrder.getPayTransactionId());
                transactionPayTransactionMapper.updateByIdNoVersion(PayTransactionConfig.getTransTableIndex(payTransaction.getUserBaseId()), payTransaction);
            } else {
                KLog.info("重复推送交易,不处理:{}", payTransaction.toJSON());
                payTransaction = null;
            }
        }
        return payTransaction;
    }

    /**
     * 发送分润mq
     *
     * @param payTransaction
     */
    private void sendMqTrade(PayTransaction payTransaction) {
        if (!payTransaction.getProfitFlag() ||
                !PayTransactionEnum.TransactionStatus.STATUS_10.isEquals(payTransaction.getStatus())) {
            return;
        }
        try {

            //收益模块mq推送
            MqPayTransationDTO mqPayTransationDTO = new MqPayTransationDTO();

            //如果是m40 则userid传入机具归属盟友的userid
            if (ChannelIdEnums.isEqualsAny(payTransaction.getChannelId(), ChannelIdEnums.yxy_jl_m40, ChannelIdEnums.YXY_JL_M50)) {
                RpcYxyTerminalBindDTO rpcYxyTerminalBindDTO = new RpcYxyTerminalBindDTO();
                rpcYxyTerminalBindDTO.setBindUserBaseId(payTransaction.getUserBaseId());
                rpcYxyTerminalBindDTO.setChannelId(payTransaction.getChannelId());
                if (StringUtils.startsWithAny(payTransaction.getSn(), "EQR","OQR")) {

                    Result<List<Terminal21>> bindList = rpcYxyTerminalService.getBindList(rpcYxyTerminalBindDTO);
                    if (!bindList.isSuccess() || CollectionUtils.isEmpty(bindList.getData())) {
                        return;
                    }
                    mqPayTransationDTO.setUserId(bindList.getData().get(0).getAllyUserBaseId());
                } else {
                    rpcYxyTerminalBindDTO.setTerminalSn(payTransaction.getSn());

                    Result<Terminal> bind = rpcYxyTerminalService.getBind(rpcYxyTerminalBindDTO);
                    if (bind.isSuccess() && Objects.nonNull(bind.getData())) {
                        mqPayTransationDTO.setUserId(bind.getData().getAllyUserBaseId());
                    } else {
                        mqPayTransationDTO.setUserId(payTransaction.getUserBaseId());
                    }
                }
            } else {
                mqPayTransationDTO.setUserId(payTransaction.getUserBaseId());
            }
            mqPayTransationDTO.setTerminalSn(payTransaction.getSn());
            mqPayTransationDTO.setMerchantNo(payTransaction.getMerchantNo());
            mqPayTransationDTO.setTransactionOrderNo(payTransaction.getOrderNo());
            mqPayTransationDTO.setTransactionAmount(payTransaction.getTransactionAmount());
            mqPayTransationDTO.setRate(payTransaction.getRate());
            mqPayTransationDTO.setTransactionTime(
                    LocalDateUtils.formatByDefaultFormat(payTransaction.getTransactionTime()));
            mqPayTransationDTO.setPlatNo(payTransaction.getPlatNo());
            mqPayTransationDTO.setChannelId(payTransaction.getChannelId());
            //查询商户优惠标识
            Merchant21Example merchant21Example = new Merchant21Example();
            merchant21Example.createCriteria().andMerchantNoEqualTo(payTransaction.getMerchantNo())
                    .andChannelIdEqualTo(payTransaction.getChannelId()).andPlatNoEqualTo(PlatNoEnums.YXY.getCode())
                    .andIsDelEqualTo(Constant.NORMAL);
            List<Merchant21> merchant21s = merchant21Mapper.selectByExample(merchant21Example);
            if(ChannelIdEnums.yxy_jl_m40.isEquals(payTransaction.getChannelId())) {
                if (payTransaction.getRate().intValue() == 0) {
                    mqPayTransationDTO.setRateType(ShareLevelRateTypeEnums.m40_vip.getRateType());
                } else {
                    mqPayTransationDTO.setRateType(ShareLevelRateTypeEnums.standard.getRateType());
                }
            } else if (CollectionUtils.isEmpty(merchant21s)) {
                mqPayTransationDTO.setRateType(ShareLevelRateTypeEnums.standard.getRateType());
            }else {
                String discountsRatePastFlag = merchant21s.get(0).getDiscountsRatePastFlag();
                if(StringUtils.equals(MerchantEnum.DiscountsRatePastFlagEnum.EFFECTIVE.getCode(), discountsRatePastFlag)){
                    mqPayTransationDTO.setRateType(ShareLevelRateTypeEnums.vip.getRateType());
                }else {
                    mqPayTransationDTO.setRateType(ShareLevelRateTypeEnums.standard.getRateType());
                }
            }

            KLog.info("开始发送分润mq:{}", mqPayTransationDTO.toJSON());

            //更新交易子表分润计算方式
            payTransaction.setProfitCalType(mqPayTransationDTO.getRateType());
            transactionPayTransactionMapper.updateByOrderNo(PayTransactionConfig.getTransTableIndex(payTransaction.getUserBaseId()), payTransaction);


            MqSendMessage mqSendMessage = new MqSendMessage();
            mqSendMessage.setTopic(MqEnum.MqTopicEnum.topic_trade_for_profit);
            mqSendMessage.setTag(MqEnum.MqTagEnum.tag_trade_for_profit);
            mqSendMessage.setSendMsg(mqPayTransationDTO.toJSON());
            mqSendMessage.setMessageKey(payTransaction.getOrderNo());

            mcenterMqService.send(mqSendMessage);
        } catch (Exception e) {
            KLog.error("【MQ-yxy分润】异常:{}", e.getMessage(), e);
        }
        KLog.info("发送分润mq结束:{}", payTransaction.toJSON());
    }

    /**
     * 保存拉卡拉交易
     *
     * @param dto 交易实体
     * @return 保存结果
     */
    @Override
    public Result lakalaDealTrade(JSONObject dto) {
        KLog.info("保存拉卡拉交易 入参:{}", dto.toJSONString());
        try {
            String merchantNo = dto.getString("customerNo");
            String terminalSn = dto.getString("posSn");
            String transactionTime = dto.getString("transTime");
            String transType = dto.getString("type");
            Merchant21 merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);

            if (Objects.isNull(merchant21)) {
                log.error("拉卡拉交易推送,商户不存在.");
                return Result.builder().fail();
            }

            Terminal21 terminal21 = rpcYxyTerminalService.getTerminalBySn(terminalSn);
            if (Objects.isNull(terminal21)) {
                log.error("拉卡拉交易推送,机具不存在.");
                return Result.builder().fail();
            }
            dto.put("channelId", terminal21.getChannelId());

            boolean toBind = Boolean.FALSE;
            if (StringUtils.isBlank(terminal21.getBindUserBaseId())) {
                log.info("商终未绑定，调用绑机接口");
                toBind = Boolean.TRUE;
            }

            // 押金交易
            if (StringUtils.equals(transType,"DEPOSIT") ) {
                log.info("押金交易，去绑机");
                toBind = Boolean.TRUE;
            }

            if (toBind) {

                Result bindResult = bindAndCreateReward(merchantNo, terminalSn, transactionTime,
                        merchant21.getUserBaseId(), terminal21.getChannelId());
                if (bindResult.isFail()) {
                    log.error("拉卡拉交易推送,商户不存在，调用Rpc接口绑机失败");
                    return Result.builder().fail();
                }
                merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);
            }

            PayTransaction payTransaction = lklPayTransactionFormat(dto, merchant21);

            //存交易
            YxyTradeService yxyTradeService = SpringContextUtils.getBean(YxyTradeService.class);
            payTransaction = yxyTradeService.saveTrade(payTransaction);

            if(Objects.nonNull(payTransaction) && LklTransTypeEnum.TYPE_412001.getTransType().equals(payTransaction.getTransType()) &&
                    (MerchantEnum.PledgeCashStatusEnum.STATUS_100.getCode().equals(merchant21.getPledgeCashStatus()) ||
                            MerchantEnum.PledgeCashStatusEnum.STATUS_0.getCode().equals(merchant21.getPledgeCashStatus()))){
                Merchant21 merchant21Up = setUpdatePledgeCashMerchant(merchant21, payTransaction);
                merchant21Mapper.updateByPrimaryKeySelective(merchant21Up);
            }
            //押金、流量卡类型，商户未返现才调激活返现
            if (Objects.nonNull(payTransaction)) {
                //调激活返现
                CheckActiveRewardYxyDTO cdto = new CheckActiveRewardYxyDTO();
                cdto.setUserBaseId(payTransaction.getUserBaseId());
                cdto.setChannelId(payTransaction.getChannelId());
                cdto.setTerminalSn(payTransaction.getSn());
                cdto.setPlatNo(PlatNoEnums.YXY.getCode());
                cdto.setTradeAmount(payTransaction.getTransactionAmount());
                cdto.setTradeTime(payTransaction.getTransactionTime());
                cdto.setOrderNo(payTransaction.getOrderNo());

                KLog.info("lakala调用检查激活返现:{}", cdto.toJSON());
                Result<Void> voidResult = merchantYxyRewardApiService.checkYxyReward(cdto);
                KLog.info("lakala检查激活返现结束:{}", voidResult.toString());
            }

        } catch (Exception e) {
            KLog.error("拉卡拉交易回调处理失败:{},入参:{}", e.getMessage(), dto.toJSONString(), e);
        }
        return Result.builder().success();
    }


    /**
     * 更新流量费
     * @param dto
     * @return
     */
    @Override
    public Result updateTradeIcc(JSONObject dto) {
        log.info("拉卡拉更新流量费，{}", dto);
        String orderNo = dto.getString("logNo");

        PayTransaction oldPay = payTransactionOrderService.getByOrderNo(orderNo);
        if (Objects.isNull(oldPay)) {
            KLog.info("原交易不存在，等待3秒, {}", dto.toJSONString());

            try {
                // 因流量费回调过快，所以如果订单不存在再等3秒
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            oldPay = payTransactionOrderService.getByOrderNo(orderNo);
            if (Objects.isNull(oldPay)) {
                KLog.info("原交易不存在, 跳过不处理 {}", dto.toJSONString());
                return Result.builder().fail(BizCodeMessages.ORDER_NO_EXISTS);
            }
        }

        // 扣款金额
        BigDecimal amount = dto.getBigDecimal("amount");

        PayTransaction updateTransaction = new PayTransaction();
        updateTransaction.setUserBaseId(oldPay.getUserBaseId());
        updateTransaction.setOrderNo(oldPay.getOrderNo());
        updateTransaction.setPayTransactionId(oldPay.getPayTransactionId());
        updateTransaction.setIccPayAmt(amount);
        updateTransaction.setTransType(LklTransTypeEnum.TYPE_012003.getTransType());
        updateTransaction.setVersion(oldPay.getVersion());
        updateTransaction.setUpdateTime(LocalDateTime.now());
        payTransactionOrderService.updateById(updateTransaction);

        Merchant21 merchant21=merchant21Mapper.selectByPrimaryKey(oldPay.getMerchantId());
        //调激活返现，触发流量费相关逻辑
        CheckActiveRewardYxyDTO cdto = new CheckActiveRewardYxyDTO();
        cdto.setUserBaseId(merchant21.getUserBaseId());
        cdto.setChannelId(merchant21.getChannelId());
        cdto.setTerminalSn(oldPay.getSn());
        cdto.setPlatNo(PlatNoEnums.YXY.getCode());
        cdto.setTradeAmount(oldPay.getTransactionAmount());
        cdto.setTradeTime(oldPay.getTransactionTime());
        cdto.setOrderNo(oldPay.getOrderNo());
        KLog.info("lakala流量费调用检查激活返现:{}", cdto.toJSON());
        Result<Void> voidResult = merchantYxyRewardApiService.checkYxyReward(cdto);
        KLog.info("lakala流量费检查激活返现结束:{}", voidResult.toString());

        return Result.builder().success();
    }

    /**
     * 更新交易手续费
     * @param dto
     * @return
     */
    @Override
    public Result updateTradeFee(JSONObject dto) {
        PayTransaction payTransaction = payTransactionOrderService.getByOrderNo(dto.getString("orderNo"));
        if (Objects.isNull(payTransaction)) {
            KLog.info("原交易不存在，跳过, {}", dto.getString("orderNo"));
            return Result.builder().fail(BizCodeMessages.ORDER_NO_EXISTS);
        }
        PayTransaction updateTransaction = new PayTransaction();
        updateTransaction.setUserBaseId(payTransaction.getUserBaseId());
        updateTransaction.setOrderNo(payTransaction.getOrderNo());
        updateTransaction.setPayTransactionId(payTransaction.getPayTransactionId());
        updateTransaction.setTransactionFee(dto.getBigDecimal("fee"));
        updateTransaction.setVersion(payTransaction.getVersion());
        updateTransaction.setUpdateTime(LocalDateTime.now());
        payTransactionOrderService.updateById(updateTransaction);

        Merchant21 merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(payTransaction.getMerchantNo());
        //调激活返现
        CheckActiveRewardYxyDTO cdto = new CheckActiveRewardYxyDTO();
        cdto.setUserBaseId(merchant21.getUserBaseId());
        cdto.setChannelId(merchant21.getChannelId());
        cdto.setTerminalSn(payTransaction.getSn());
        cdto.setPlatNo(PlatNoEnums.YXY.getCode());
        cdto.setTradeAmount(payTransaction.getTransactionAmount());
        cdto.setTradeTime(payTransaction.getTransactionTime());
        cdto.setOrderNo(payTransaction.getOrderNo());

        KLog.info("lakala流量费调用检查激活返现:{}", cdto.toJSON());
        Result<Void> voidResult = merchantYxyRewardApiService.checkYxyReward(cdto);
        KLog.info("lakala流量费检查激活返现结束:{}", voidResult.toString());

        // 发放分润
        if(Objects.equals(merchant21.getChannelId(), ChannelIdEnums.YRB_LKL_EPOS.getCode()) || Objects.equals(merchant21.getChannelId(), ChannelIdEnums.YRB_LKL_SPOS.getCode())) {
            payTransaction.setRateStr(dto.getString("rate"));
            //如果是拉卡拉扫码交易，需要更新之前写入的交易费率数据
            if(Objects.equals(payTransaction.getRateStr(), "0.0048")) {
                String processedStr = payTransaction.getRateStr().replace(".", ""); // 变成"00048"
                int result = Integer.parseInt(processedStr);
                payTransaction.setRate(result);
                String postUrlRate = "https://testapi.mugeyrb.com/transaction/update/rate?orderNum="+dto.getString("orderNo")+"&rate="+result;
                if (commonService.isProd()) {
                    postUrlRate = "http://172.17.187.6:8886/transaction/update/rate?orderNum="+dto.getString("orderNo")+"&rate="+result;
                }
                try {
                    HttpClientUtil.httpGetRequest(postUrlRate);
                } catch (Exception e) {
                    e.printStackTrace();
                }
//                payTransaction.setRate(result);
//                PayTransaction uppo = new PayTransaction();
//                BeanUtils.copyProperties(payTransaction, uppo);
//                uppo.setPayTransactionId(payTransaction.getPayTransactionId());
//                //uppo.setVersion(payTransaction.getVersion());
//                uppo.setUpdateTime(LocalDateTime.now());
//                payTransactionOrderService.updateById(uppo);
            }
        }
        payEposService.profitOpt(payTransaction);

        //私信调用
        payEposService.sendTransactionLetter(payTransaction);

        return Result.builder().success();
    }

    /**
     * 更新D0手续费
     * @param dto
     * @return
     */
    @Override
    public Result updateTradeD0Fee(JSONObject dto) {
        String orderNo = dto.getString("oldSeqNo");
        if (StringUtils.isBlank(orderNo)) {
            KLog.info("秒提订单不处理，跳过, {}", dto.toJSONString());
            return Result.builder().success();
        }
        PayTransaction oldPay = payTransactionOrderService.getByOrderNo(orderNo);
        if (Objects.isNull(oldPay)) {
            KLog.info("原交易不存在，跳过, {}", dto.getString("oldSeqNo"));
            return Result.builder().fail(BizCodeMessages.ORDER_NO_EXISTS);
        }

        String txtStat = dto.getString("txtStat");
        if (StringUtils.equals("00", txtStat)) {
            // D0⼿续费
            BigDecimal feeAmt = dto.getBigDecimal("feeAmt");
            // 记账⾦额
            BigDecimal accAmt = dto.getBigDecimal("accAmt");
            PayTransaction updateTransaction = new PayTransaction();
            updateTransaction.setUserBaseId(oldPay.getUserBaseId());
            updateTransaction.setOrderNo(oldPay.getOrderNo());
            updateTransaction.setPayTransactionId(oldPay.getPayTransactionId());
            updateTransaction.setFeeAmt(feeAmt);
            updateTransaction.setAccAmt(accAmt);
            updateTransaction.setVersion(oldPay.getVersion());
            updateTransaction.setUpdateTime(LocalDateTime.now());
            payTransactionOrderService.updateById(updateTransaction);
        }
        return Result.builder().success();
    }




    /**
     * 商户通知
     * @param jsonObject
     * @return
     */
    @Override
    public Result lakalaMerchantNotice(JSONObject jsonObject) {

        log.info("拉卡拉商户通知");

        String dateStr = LocalDateUtils.formatByDefaultFormat(LocalDateTime.now());

        SaveMerchantDTO dto = new SaveMerchantDTO();
        dto.setMerchantNo(jsonObject.getString("customerNo"));
        dto.setUnionpayMerchantNo(jsonObject.getString("externalCustomerNo"));
        dto.setUserName(jsonObject.getString("customerName"));
        dto.setRealName(jsonObject.getString("legalName"));
        dto.setAgentNo(jsonObject.getString("agentNo"));
        dto.setRegistTime(dateStr);
        dto.setAuthTime(dateStr);
        dto.setPhone(jsonObject.getString("legalPhoneNo"));
        dto.setIdCard(jsonObject.getString("identityNo"));
        dto.setAgentNo(jsonObject.getString("agencyNo"));
        dto.setContractId(jsonObject.getString("contractId"));
        dto.setActivationCodes(jsonObject.getString("activeNo"));
        dto.setActiveTime(dateStr);
        dto.setPushWay(YsPaySaveMerchantDTO.PUSH_WAY_MERCHANT);
        return merchantYxyApiService.saveMerchant(dto);
    }

    /**
     * 商终绑定
     * @param jsonObject
     * @return
     */
    @Override
    public Result lakalaMerchantBind(JSONObject jsonObject) {

        log.info("拉卡拉商户绑定， {}", jsonObject);
        String unionpayMerchantNo = jsonObject.getString("externalCustomerNo");
        String terminalSn = jsonObject.getString("posSn");
        String bindTime = jsonObject.getString("operateTime");

        // 检查商户 和机具是否存在
        Merchant21Example merchant21Example = new Merchant21Example();
        merchant21Example.createCriteria().andUnionpayMerchantNoEqualTo(unionpayMerchantNo);
        List<Merchant21> merchant21s= merchant21Mapper.selectByExample(merchant21Example);
        if (CollectionUtils.isEmpty(merchant21s)) {
            log.info("商户不存在，unionpayMerchantNo={}", unionpayMerchantNo);
            return Result.builder().fail();
        }
        Merchant21 merchant21 = merchant21s.get(0);
        String merchantNo = merchant21.getMerchantNo();
        String merchantUserBaseId = merchant21.getUserBaseId();

        Terminal21 terminal21 = rpcYxyTerminalService.getTerminalBySn(terminalSn);
        if (Objects.isNull(terminal21)) {
            log.info("机具不存在，terminalSn={}", terminalSn);
            return Result.builder().fail();
        }

        String bindUserBaseId = terminal21.getBindUserBaseId();
        if (StringUtils.isNotEmpty(bindUserBaseId)) {
            if (StringUtils.equals(merchantUserBaseId, bindUserBaseId)) {
                log.info("机具已绑定，terminalSn={}, merchantNo={}", terminalSn, merchantNo);
                return Result.builder().success();
            } else {
                log.info("机具已绑定，需要换绑，terminalSn={}, merchantNo={}", terminalSn, merchantNo);
            }
        }

        return bindAndCreateReward(merchantNo, terminalSn, bindTime, merchantUserBaseId, terminal21.getChannelId());
    }


    /**
     * 调用绑机接口
     * @param merchantNo
     * @param sn
     * @param bindTime
     * @return
     */
    @Override
    public Result bindAndCreateReward(String merchantNo, String sn, String bindTime, String merchantUserBaseId, Short channelId) {
        // 调用绑机接口
        RpcYxyCallbackBindDTO dto = new RpcYxyCallbackBindDTO();
        dto.setMerchantNo(merchantNo);
        dto.setMerchantBindTime(LocalDateUtils.stringToLocalDateTime(bindTime));
        dto.setSn(sn);
        dto.setUserBaseId(merchantUserBaseId);
        dto.setChannelId(channelId);

        log.info("rpc调用terminal绑定机具， {}", dto);
        Result<Terminal> terminalResult = rpcYxyTerminalService.callbackBind(dto);
        if (Objects.isNull(terminalResult) || terminalResult.isFail() || Objects.isNull(terminalResult.getData())) {
            log.error("调用绑定机具失败。merchantNo={}, terminalSn={}", merchantNo, sn);
            return Result.builder().fail();
        }

        Terminal terminal = terminalResult.getData();

        // rpc调用merchant更新商户信息并关联真实用户
        SaveMerchantDTO mdto = new SaveMerchantDTO();
        mdto.setUserBaseId(terminal.getBindUserBaseId());
        mdto.setTerminalSn(terminal.getTerminalSn());
        mdto.setPushWay(SaveMerchantDTO.PUSH_WAY_POS);
        mdto.setTerminalRateId(terminal.getTerminalRateId());
        mdto.setChannelId(terminal.getChannelId());
        mdto.setBindTime(bindTime);
        mdto.setMerchantNo(merchantNo);

        Result result = merchantYxyApiService.saveMerchant(mdto);
        if (Objects.nonNull(result) && result.isSuccess()) {
            Merchant21 merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);
            // 创建激活返现
            CreateRewardYxyDTO cdto = new CreateRewardYxyDTO();
            cdto.setChannelId(terminal.getChannelId());
            cdto.setTerminalSn(terminal.getTerminalSn());
            cdto.setActiveTime(terminal.getMerchantBindTime());
            cdto.setPlatNo(PlatNoEnums.YXY.getCode());
            cdto.setFromUserBaseId(terminal.getBindUserBaseId());
            cdto.setToUserBaseId(terminal.getAllyUserBaseId());
            cdto.setTerminalRateId(terminal.getTerminalRateId());
            cdto.setTerminalPolicyName(terminal.getTerminalPolicyName());
            cdto.setRewardExpiredTime(terminal.getRefundOutTime());
            cdto.setMerchantId(merchant21.getMerchantId());
            KLog.info("调用创建激活返现:{}", cdto.toJSON());
            Result<Void> voidResult = merchantYxyRewardApiService.createRewardYxy(cdto);
            KLog.info("创建激活返现结束:{}", voidResult.toString());

            if (voidResult.isSuccess()) {
                return Result.builder().success();
            } else {
                log.error("绑定机具 创建激活返现失败。merchantNo={}, terminalSn={}", merchantNo, sn);
            }
        } else {
            log.error("绑定机具更新商户失败。merchantNo={}, terminalSn={}", merchantNo, sn);
        }
        return Result.builder().fail();
    }

    @Override
    public Result hlbDealTrade(JSONObject dto) {
        KLog.info("保存合利宝交易 入参:{}", dto.toJSONString());
        try {
            String merchantNo = dto.getString("userId");
            String terminalSn = dto.getString("tusn");
            String transactionTime = dto.getString("finishDate");
            Merchant21 merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);

            if (Objects.isNull(merchant21)) {
                log.error("合利宝交易推送,商户不存在.");
                return Result.builder().fail();
            }

            Terminal21 terminal21 = rpcYxyTerminalService.getTerminalBySn(terminalSn);
            if (Objects.isNull(terminal21)) {
                log.error("合利宝交易推送,机具不存在.");
                return Result.builder().fail();
            }
            dto.put("channelId", ChannelIdEnums.YRB_HLB_EPOS.getCode());

            boolean toBind = Boolean.FALSE;
            if (StringUtils.isBlank(terminal21.getBindUserBaseId())) {
                log.info("商终未绑定，调用绑机接口");
                toBind = Boolean.TRUE;
            }

            Integer transactionId = transactionPayTransactionMapper.existTransactionByMerchant(PayTransactionUtil.getTransTableIndex(terminal21.getBindUserBaseId()), merchantNo);
            // 首次交易
            if (Objects.isNull(transactionId) && merchant21.getBountyFlag() == 0) {
                log.info("首次流量费交易，去绑机");
                toBind = Boolean.TRUE;
            }

            if (toBind) {
                Result bindResult = bindAndCreateReward(merchantNo, terminalSn, transactionTime,
                        merchant21.getUserBaseId(), terminal21.getChannelId());
                if (bindResult.isFail()) {
                    log.error("合利宝交易推送, 调用Rpc接口绑机失败");
                    return Result.builder().fail();
                }
                merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);
            }

            PayTransaction payTransaction = payTransactionFormatHlb(dto, merchant21);

            //存交易
            YxyTradeService yxyTradeService = SpringContextUtils.getBean(YxyTradeService.class);
            payTransaction = yxyTradeService.saveTrade(payTransaction);

            //押金、流量卡类型，商户未返现才调激活返现
            if (Objects.nonNull(payTransaction) && merchant21.getBountyFlag() == MerchantEnum.BountyFlagEnum.no.getCode().byteValue()) {
                //调激活返现
                CheckActiveRewardYxyDTO cdto = new CheckActiveRewardYxyDTO();
                cdto.setUserBaseId(payTransaction.getUserBaseId());
                cdto.setChannelId(payTransaction.getChannelId());
                cdto.setTerminalSn(payTransaction.getSn());
                cdto.setPlatNo(PlatNoEnums.YXY.getCode());
                cdto.setTradeAmount(payTransaction.getTransactionAmount());
                cdto.setTradeTime(payTransaction.getTransactionTime());
                cdto.setOrderNo(payTransaction.getOrderNo());

                KLog.info("合利宝调用检查激活返现:{}", cdto.toJSON());
                Result<Void> voidResult = merchantYxyRewardApiService.checkYxyReward(cdto);
                KLog.info("合利宝检查激活返现结束:{}", voidResult.toString());
            }

            if(Objects.nonNull(payTransaction) && LklTransTypeEnum.TYPE_012003.getTransType().equals(payTransaction.getTransType()) && (
                    MerchantEnum.PledgeCashStatusEnum.STATUS_100.getCode().equals(merchant21.getPledgeCashStatus()) ||
                            MerchantEnum.PledgeCashStatusEnum.STATUS_0.getCode().equals(merchant21.getPledgeCashStatus()))){
                Merchant21 merchant21Up = setUpdatePledgeCashMerchant(merchant21, payTransaction);
                merchant21Mapper.updateByPrimaryKeySelective(merchant21Up);
            }
            // 计入分润
            payEposService.profitOpt(payTransaction);
            //私信调用
            payEposService.sendTransactionLetter(payTransaction);
        } catch (Exception e) {
            KLog.error("保存合利宝交易处理失败:{},入参:{}", e.getMessage(), dto.toJSONString(), e);
        }
        return Result.builder().success();
    }

    @Override
    public Result zfAndYsDealTrade(JSONObject dto) {
        KLog.info("中付银盛交易 入参:{}", dto.toJSONString());
        try {
            String merchantNo = dto.getString("merchant_no");
            String transactionTime = dto.getString("trans_time");
            Merchant21 merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);

            if (Objects.isNull(merchant21)) {
                log.error("中付银盛交易,商户不存在.");
                return Result.builder().fail();
            }
            dto.put("channelId", merchant21.getChannelId());

            Terminal21 terminal21 = terminal21Mapper.selectByPrimaryKey(merchant21.getTerminalId());
            if (Objects.isNull(terminal21)) {
                log.error("中付银盛交易,机具不存在.");
                return Result.builder().fail();
            }

            boolean toBind = Boolean.FALSE;
            MerchantPledgeCashPolicy merchantPledgeCashPolicy = merchantPledgeCashPolicyMapper.selectByPrimaryKey(terminal21.getMerchantPledgeCashPolicyId());
            Integer transactionId = transactionPayTransactionMapper.existTransactionByMerchant(PayTransactionUtil.getTransTableIndex(terminal21.getBindUserBaseId()), merchantNo);

            PayTransaction payTransaction = payTransactionFormatZfAndYs(dto, merchant21);
            // 首次交易
            if (Objects.isNull(transactionId) && BigDecimal.ZERO.compareTo(merchantPledgeCashPolicy.getPledgeCashPayAmount())==0) {
                log.info("首次交易，去绑机");
                toBind = Boolean.TRUE;
            } else if (BigDecimal.ZERO.compareTo(merchantPledgeCashPolicy.getPledgeCashPayAmount()) < 0 &&
                    LklTransTypeEnum.TYPE_412001.getTransType().equals(payTransaction.getTransType())) {
                toBind = Boolean.TRUE;
                log.info("押金交易，去绑机");
            }

            if (toBind) {
                Result bindResult = bindAndCreateReward(merchantNo, terminal21.getTerminalSn(), transactionTime, merchant21.getUserBaseId(), terminal21.getChannelId());
                if (bindResult.isFail()) {
                    log.error("中付银盛交易, 调用Rpc接口绑机失败");
                    return Result.builder().fail();
                }
                merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);
            }

            //存交易
            YxyTradeService yxyTradeService = SpringContextUtils.getBean(YxyTradeService.class);
            payTransaction = yxyTradeService.saveTrade(payTransaction);

            //押金、商户未返现才调激活返现
            if (Objects.nonNull(payTransaction)) {
                //调激活返现
                CheckActiveRewardYxyDTO cdto = new CheckActiveRewardYxyDTO();
                cdto.setUserBaseId(payTransaction.getUserBaseId());
                cdto.setChannelId(payTransaction.getChannelId());
                cdto.setTerminalSn(payTransaction.getSn());
                cdto.setPlatNo(PlatNoEnums.YXY.getCode());
                cdto.setTradeAmount(payTransaction.getTransactionAmount());
                cdto.setTradeTime(payTransaction.getTransactionTime());
                cdto.setOrderNo(payTransaction.getOrderNo());

                KLog.info("中付银盛激活返现:{}", cdto.toJSON());
                Result<Void> voidResult = merchantYxyRewardApiService.checkYxyReward(cdto);
                KLog.info("中付银盛激活返现结束:{}", voidResult.toString());
            }

            if (Objects.nonNull(payTransaction) && LklTransTypeEnum.TYPE_412001.getTransType().equals(payTransaction.getTransType()) && (
                    MerchantEnum.PledgeCashStatusEnum.STATUS_100.getCode().equals(merchant21.getPledgeCashStatus()))) {
                Merchant21 merchant21Up = setUpdatePledgeCashMerchant(merchant21, payTransaction);
                merchant21Mapper.updateByPrimaryKeySelective(merchant21Up);
            }
            // 计入分润
            payEposService.profitOpt(payTransaction);
            //私信调用
            payEposService.sendTransactionLetter(payTransaction);
        } catch (Exception e) {
            KLog.error("中付银盛交易处理失败:{},入参:{}", e.getMessage(), dto.toJSONString(), e);
        }
        return Result.builder().success();
    }

    @Override
    public Result zfAndYsUpdateTrade(JSONObject jTransaction) {
        PayTransactionIndexExample payTransactionIndexExample = new PayTransactionIndexExample();
        payTransactionIndexExample.createCriteria()
                .andOrderNoEqualTo(jTransaction.getString("source_id")).andPlatNoEqualTo(PlatNoEnums.YXY.getCode());
        List<PayTransactionIndex> payTransactionIndices = payTransactionIndexMapper.selectByExample(payTransactionIndexExample);
        if (CollectionUtils.isNotEmpty(payTransactionIndices)) {
            PayTransaction updateTransaction = new PayTransaction();
            updateTransaction.setOrderNo(jTransaction.getString("source_id"));
            updateTransaction.setTransactionAmount(jTransaction.getBigDecimal("out_amount"));
            updateTransaction.setFeeAmt(jTransaction.getBigDecimal("fee_amount"));
            transactionPayTransactionMapper.updateByOrderNo(payTransactionIndices.get(0).getTableIndex(), updateTransaction);
        }
        return Result.builder().success();
    }

    @Override
    public Result ydcDealTrade(JSONObject jTransaction) {
        KLog.info("银多财交易 入参:{}", jTransaction.toJSONString());
        try {
            String merchantNo = jTransaction.getString("merchantNo");
            String transactionTime = jTransaction.getString("transTime");
            Merchant21 merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);

            if (Objects.isNull(merchant21)) {
                log.error("银多财交易,商户不存在.");
                return Result.builder().fail();
            }
            jTransaction.put("channelId", merchant21.getChannelId());

            Terminal21 terminal21 = terminal21Mapper.selectByPrimaryKey(merchant21.getTerminalId());
            if (Objects.isNull(terminal21)) {
                log.error("银多财交易,机具不存在.");
                return Result.builder().fail();
            }

            boolean toBind = Boolean.FALSE;
            MerchantPledgeCashPolicy merchantPledgeCashPolicy = merchantPledgeCashPolicyMapper.selectByPrimaryKey(terminal21.getMerchantPledgeCashPolicyId());
            Integer transactionId = transactionPayTransactionMapper.existTransactionByMerchant(PayTransactionUtil.getTransTableIndex(terminal21.getBindUserBaseId()), merchantNo);

            PayTransaction payTransaction = payTransactionFormatYdc(jTransaction, merchant21);
            // 首次交易
            if (Objects.isNull(transactionId) && BigDecimal.ZERO.compareTo(merchantPledgeCashPolicy.getPledgeCashPayAmount())==0) {
                log.info("首次交易，去绑机");
                toBind = Boolean.TRUE;
            } else if (BigDecimal.ZERO.compareTo(merchantPledgeCashPolicy.getPledgeCashPayAmount()) < 0 &&
                    LklTransTypeEnum.TYPE_412001.getTransType().equals(payTransaction.getTransType())) {
                toBind = Boolean.TRUE;
                log.info("押金交易，去绑机");
            }

            if (toBind) {
                Result bindResult = bindAndCreateReward(merchantNo, terminal21.getTerminalSn(), transactionTime, merchant21.getUserBaseId(), terminal21.getChannelId());
                if (bindResult.isFail()) {
                    log.error("银多财交易, 调用Rpc接口绑机失败");
                    return Result.builder().fail();
                }
                merchant21 = merchantYxyApiService.getMerchant21ByMerchantNo(merchantNo);
            }

            //存交易
            YxyTradeService yxyTradeService = SpringContextUtils.getBean(YxyTradeService.class);
            payTransaction = yxyTradeService.saveTrade(payTransaction);

            //押金、商户未返现才调激活返现
            if (Objects.nonNull(payTransaction)) {
                //调激活返现
                CheckActiveRewardYxyDTO cdto = new CheckActiveRewardYxyDTO();
                cdto.setUserBaseId(payTransaction.getUserBaseId());
                cdto.setChannelId(payTransaction.getChannelId());
                cdto.setTerminalSn(payTransaction.getSn());
                cdto.setPlatNo(PlatNoEnums.YXY.getCode());
                cdto.setTradeAmount(payTransaction.getTransactionAmount());
                cdto.setTradeTime(payTransaction.getTransactionTime());
                cdto.setOrderNo(payTransaction.getOrderNo());

                KLog.info("银多财激活返现:{}", cdto.toJSON());
                Result<Void> voidResult = merchantYxyRewardApiService.checkYxyReward(cdto);
                KLog.info("银多财激活返现结束:{}", voidResult.toString());
            }

            if (Objects.nonNull(payTransaction) && LklTransTypeEnum.TYPE_412001.getTransType().equals(payTransaction.getTransType()) && (
                    MerchantEnum.PledgeCashStatusEnum.STATUS_100.getCode().equals(merchant21.getPledgeCashStatus()))) {
                Merchant21 merchant21Up = setUpdatePledgeCashMerchant(merchant21, payTransaction);
                merchant21Mapper.updateByPrimaryKeySelective(merchant21Up);
            }
            // 计入分润
            payEposService.profitOpt(payTransaction);
            //私信调用
            payEposService.sendTransactionLetter(payTransaction);
        } catch (Exception e) {
            KLog.error("中付银盛交易处理失败:{},入参:{}", e.getMessage(), jTransaction.toJSONString(), e);
        }
        return Result.builder().success();
    }

    @Override
    public Result ydcUpdateTrade(JSONObject jSettle) {
        PayTransactionIndexExample payTransactionIndexExample = new PayTransactionIndexExample();
        payTransactionIndexExample.createCriteria()
                .andOrderNoEqualTo(jSettle.getString("serialNo")).andPlatNoEqualTo(PlatNoEnums.YXY.getCode());
        List<PayTransactionIndex> payTransactionIndices = payTransactionIndexMapper.selectByExample(payTransactionIndexExample);
        if (CollectionUtils.isNotEmpty(payTransactionIndices)) {
            PayTransaction updateTransaction = new PayTransaction();
            updateTransaction.setOrderNo(jSettle.getString("serialNo"));
            updateTransaction.setFeeAmt(jSettle.getBigDecimal("feeAmount"));
            updateTransaction.setAccAmt(jSettle.getBigDecimal("outAmount"));
            transactionPayTransactionMapper.updateByOrderNo(payTransactionIndices.get(0).getTableIndex(), updateTransaction);
        }
        return Result.builder().success();
    }

    private Merchant21 setUpdatePledgeCashMerchant(Merchant21 merchant21, PayTransaction payTransaction) {
        Merchant21 merchant21Up=new Merchant21();
        merchant21Up.setMerchantId(merchant21.getMerchantId());
        merchant21Up.setPledgeCash(payTransaction.getTransactionAmount());
        merchant21Up.setPledgeCashSuccessTime(payTransaction.getTransactionTime());
        merchant21Up.setPledgeCashOrderNo(payTransaction.getOrderNo());
        merchant21Up.setPledgeCashSerialNo(payTransaction.getOrderNo());
        merchant21Up.setPledgeCashStatus(MerchantEnum.PledgeCashStatusEnum.STATUS_200.getCode());
        return merchant21Up;
    }

    private PayTransaction payTransactionFormatHlb(JSONObject dto, Merchant21 merchant21) {
        PayTransaction payTransaction = new PayTransaction();

        payTransaction.setUserBaseId(merchant21.getUserBaseId());
        payTransaction.setMerchantId(merchant21.getMerchantId());
        payTransaction.setMerchantNo(merchant21.getMerchantNo());
        payTransaction.setMerchantName(merchant21.getMerchantName());
        payTransaction.setPhone(merchant21.getPhone());
        payTransaction.setRealName(merchant21.getRealName());
        payTransaction.setTransType(LklTransTypeEnum.TYPE_012001.getTransType());
        if (dto.getInteger("simFee") > 0){
            payTransaction.setTransType(LklTransTypeEnum.TYPE_012003.getTransType());
        }
        BigDecimal amount = dto.getBigDecimal("orderAmount");
        payTransaction.setOrderNo(dto.getString("agentOrderId"));
        payTransaction.setTransactionNo(dto.getString("agentOrderId"));
        payTransaction.setTransactionAmount(amount);
        payTransaction.setCardFlag(formatCardFlagHlb(dto.getString("posTradeType")));
        payTransaction.setSn(dto.getString("tusn"));
        payTransaction.setChannelId(ChannelIdEnums.YRB_HLB_EPOS.getCode());
        payTransaction.setTransactionBank(dto.getString("bankName"));
        payTransaction.setTransactionCardType(payTransaction.getCardFlag());
        payTransaction.setStatus(PayTransactionEnum.TransactionStatus.STATUS_10.getCode());
        payTransaction.setRate(dto.getBigDecimal("memberFeeRate").multiply(new BigDecimal("10000")).intValue());

        String transTime = dto.getString("finishDate");
        payTransaction.setTransactionTime(LocalDateUtils.parseLocalDateTimeByDefaultFormat(transTime));
        payTransaction.setTransactionMonth(StringUtils.left(StringUtils.replace(transTime,"-", ""), 6));
        payTransaction.setTransactionDay(StringUtils.left(StringUtils.replace(transTime,"-", ""), 8));
        payTransaction.setFrontSuccessTime(payTransaction.getTransactionTime());
        payTransaction.setFeeAmt(dto.getBigDecimal("singleFee"));
        payTransaction.setTransactionFee(dto.getBigDecimal("memberFee"));
        payTransaction.setPlatNo(merchant21.getPlatNo());
        payTransaction.setIsDel(false);
        payTransaction.setProfitFlag(checkIsProfitFlag(payTransaction));
        return payTransaction;
    }

    /**
     * 格式化中付银盛交易
     */
    private PayTransaction payTransactionFormatZfAndYs(JSONObject dto, Merchant21 merchant21) {
        PayTransaction payTransaction = new PayTransaction();

        payTransaction.setUserBaseId(merchant21.getUserBaseId());
        payTransaction.setMerchantId(merchant21.getMerchantId());
        payTransaction.setMerchantNo(merchant21.getMerchantNo());
        payTransaction.setMerchantName(merchant21.getMerchantName());
        payTransaction.setPhone(merchant21.getPhone());
        payTransaction.setRealName(merchant21.getRealName());
        payTransaction.setTransType(LklTransTypeEnum.TYPE_012001.getTransType());
        if (StringUtils.isNotEmpty(dto.getString("flow_amount")) && new BigDecimal(dto.getString("flow_amount")).compareTo(BigDecimal.ZERO) > 0) {
            payTransaction.setTransType(LklTransTypeEnum.TYPE_012003.getTransType());
            payTransaction.setIccPayAmt(dto.getBigDecimal("flow_amount"));
        }
        if (StringUtils.equals(dto.getString("order_type"), "3")) {
            payTransaction.setTransType(LklTransTypeEnum.TYPE_412001.getTransType());
        }
        BigDecimal amount = dto.getBigDecimal("trans_amount");
        payTransaction.setOrderNo(dto.getString("order_no"));
        payTransaction.setTransactionNo(dto.getString("order_no"));
        payTransaction.setTransactionAmount(amount);
        payTransaction.setCardFlag(formatCardFlagZfAndYs(dto.getString("card_type"), dto.getString("trans_type")));
        payTransaction.setSn(dto.getString("terminal_id"));
        payTransaction.setChannelId(dto.getShort("channelId"));
        payTransaction.setTransactionCardType(payTransaction.getCardFlag());
        payTransaction.setStatus(PayTransactionEnum.TransactionStatus.STATUS_10.getCode());
        payTransaction.setRate(new BigDecimal(StringUtils.replace(dto.getString("trans_rate"), "%", "")).multiply(new BigDecimal("100")).intValue());

        String transTime = dto.getString("trans_time");
        payTransaction.setTransactionTime(LocalDateUtils.parseLocalDateTimeByDefaultFormat(transTime));
        payTransaction.setTransactionMonth(StringUtils.left(StringUtils.replace(transTime, "-", ""), 6));
        payTransaction.setTransactionDay(StringUtils.left(StringUtils.replace(transTime, "-", ""), 8));
        payTransaction.setFrontSuccessTime(payTransaction.getTransactionTime());
        payTransaction.setTransactionFee(dto.getBigDecimal("trans_fee"));
        payTransaction.setPlatNo(merchant21.getPlatNo());
        payTransaction.setIsDel(false);
        payTransaction.setProfitFlag(checkIsProfitFlag(payTransaction));
        return payTransaction;
    }

    /**
     * 格式化银多财交易
     */
    private PayTransaction payTransactionFormatYdc(JSONObject dto, Merchant21 merchant21) {
        PayTransaction payTransaction = new PayTransaction();

        payTransaction.setUserBaseId(merchant21.getUserBaseId());
        payTransaction.setMerchantId(merchant21.getMerchantId());
        payTransaction.setMerchantNo(merchant21.getMerchantNo());
        payTransaction.setMerchantName(merchant21.getMerchantName());
        payTransaction.setPhone(merchant21.getPhone());
        payTransaction.setRealName(merchant21.getRealName());
        payTransaction.setTransType(LklTransTypeEnum.TYPE_012001.getTransType());
        //流量费
        if (StringUtils.equals(dto.getString("flowFeeFlag"), "1")
                && StringUtils.isNotEmpty(dto.getString("vasFlowFee"))
                && new BigDecimal(dto.getString("vasFlowFee")).compareTo(BigDecimal.ZERO) > 0) {
            payTransaction.setTransType(LklTransTypeEnum.TYPE_012003.getTransType());
            payTransaction.setIccPayAmt(dto.getBigDecimal("vasFlowFee"));
        }
        //服务费
        if (StringUtils.equals(dto.getString("activityTransFlag"), "1")) {
            payTransaction.setTransType(LklTransTypeEnum.TYPE_412001.getTransType());
        }
        BigDecimal amount = dto.getBigDecimal("transAmount");
        payTransaction.setOrderNo(dto.getString("serialNo"));
        payTransaction.setTransactionNo(dto.getString("serialNo"));
        payTransaction.setTransactionAmount(amount);
        payTransaction.setCardFlag(formatCardFlagYdc(dto.getString("cardType"), dto.getString("payType")));
        payTransaction.setSn(dto.getString("terminalId"));
        payTransaction.setChannelId(dto.getShort("channelId"));
        payTransaction.setTransactionCardType(payTransaction.getCardFlag());
        payTransaction.setStatus(PayTransactionEnum.TransactionStatus.STATUS_10.getCode());
        payTransaction.setRate(new BigDecimal(dto.getString("transRate")).multiply(new BigDecimal("10000")).intValue());

        String transTime = dto.getString("transTime");
        payTransaction.setTransactionTime(LocalDateUtils.parseLocalDateTimeByDefaultFormat(transTime));
        payTransaction.setTransactionMonth(StringUtils.left(StringUtils.replace(transTime, "-", ""), 6));
        payTransaction.setTransactionDay(StringUtils.left(StringUtils.replace(transTime, "-", ""), 8));
        payTransaction.setFrontSuccessTime(payTransaction.getTransactionTime());
        payTransaction.setTransactionFee(dto.getBigDecimal("transFee"));
        payTransaction.setPlatNo(merchant21.getPlatNo());
        payTransaction.setIsDel(false);
        payTransaction.setProfitFlag(checkIsProfitFlag(payTransaction));
        return payTransaction;
    }

    private String formatCardFlagYdc(String crdFlg, String payType) {
        if ("CREDIT".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode();
        } else if ("DEBIT".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.BORROW_CARD.getCode();
        } else if (StringUtils.startsWith(payType, "WX")) {
            return PayTransactionEnum.CardFlagEnum.WECHAT.getCode();
        } else if (StringUtils.startsWith(payType, "ZFB")) {
            return PayTransactionEnum.CardFlagEnum.ALIPAY.getCode();
        } else if (StringUtils.startsWith(payType, "YL")) {
            return PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode();
        } else {
            return payType;
        }
    }

    private String formatCardFlagHlb(String crdFlg) {
        if ("POS_CREDIT".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode();
        } else if ("POS_DEBIT".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.BORROW_CARD.getCode();
        } else if ("WXPAY".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.WECHAT.getCode();
        } else if ("ALIPAY".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.ALIPAY.getCode();
        } else if ("POS_FLASH".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode();
        } else if ("UNIONPAY".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode();
        }  else if ("VIP".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode();
        } else {
            return crdFlg;
        }
    }

    private String formatCardFlagZfAndYs(String crdFlg, String payType) {
        if ("1".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode();
        } else if ("2".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.BORROW_CARD.getCode();
        } else if ("3".equals(payType) || "6".equals(payType)) {
            return PayTransactionEnum.CardFlagEnum.WECHAT.getCode();
        } else if ("2".equals(payType) || "7".equals(payType)) {
            return PayTransactionEnum.CardFlagEnum.ALIPAY.getCode();
        } else {
            return PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode();
        }
    }

    /**
     * 格式化拉卡拉交易
     * @param dto
     * @param merchant21
     * @return
     */
    public PayTransaction lklPayTransactionFormat(JSONObject dto, Merchant21 merchant21) {

        PayTransaction payTransaction = new PayTransaction();

        payTransaction.setUserBaseId(merchant21.getUserBaseId());
        payTransaction.setMerchantId(merchant21.getMerchantId());
        payTransaction.setMerchantNo(merchant21.getMerchantNo());
        payTransaction.setMerchantName(merchant21.getMerchantName());
        payTransaction.setPhone(merchant21.getPhone());
        payTransaction.setRealName(merchant21.getRealName());
        payTransaction.setSysRef(dto.getString("srefNo"));
        if (StringUtils.equals(dto.getString("type"),"DEPOSIT")) {
            // 押金交易
            payTransaction.setTransType(LklTransTypeEnum.TYPE_412001.getTransType());
        } else {
            payTransaction.setTransType(LklTransTypeEnum.TYPE_012001.getTransType());
        }

        BigDecimal amount = dto.getBigDecimal("amount").divide(new BigDecimal("100"));
        payTransaction.setOrderNo(dto.getString("orderNo"));
        payTransaction.setTransactionNo(dto.getString("orderNo"));
        payTransaction.setTransactionAmount(amount);
        payTransaction.setCardFlag(formatCardFlag(dto.getString("transCardType")));
        payTransaction.setSn(dto.getString("posSn"));
        payTransaction.setChannelId(dto.getShort("channelId"));
        payTransaction.setTransactionCardNo(dto.getString("cardNo"));
        payTransaction.setTransactionCardType(payTransaction.getCardFlag());
        payTransaction.setStatus(PayTransactionEnum.TransactionStatus.STATUS_10.getCode());
        payTransaction.setRate(merchant21.getRateCredit());
        String transTime = dto.getString("transTime");

        payTransaction.setTransactionTime(LocalDateUtils.parseLocalDateTimeByDefaultFormat(transTime));
        payTransaction.setTransactionMonth(StringUtils.left(StringUtils.replace(transTime,"-", ""), 6));
        payTransaction.setTransactionDay(StringUtils.left(StringUtils.replace(transTime,"-", ""), 8));
        payTransaction.setFrontSuccessTime(payTransaction.getTransactionTime());
        payTransaction.setFeeAmt(BigDecimal.ZERO);
        payTransaction.setPlatNo(merchant21.getPlatNo());
        payTransaction.setIsDel(false);
        payTransaction.setProfitFlag(checkIsProfitFlag(payTransaction));
        return payTransaction;
    }

    /**
     * 格式化卡类型
     *
     * @param crdFlg 卡类型
     * @return 银小云卡类型
     */
    private String formatCardFlag(String crdFlg) {
        if ("01".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode();
        } else if ("00".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.BORROW_CARD.getCode();
        } else if ("91".equals(crdFlg) || "88".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.WECHAT.getCode();
        } else if ("92".equals(crdFlg) || "89".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.ALIPAY.getCode();
        } else if ("94".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode();
        } else if ("81".equals(crdFlg) || "22".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.UNIONCODE_DEBIT.getCode();
        }  else if ("82".equals(crdFlg) || "21".equals(crdFlg)) {
            return PayTransactionEnum.CardFlagEnum.UNIONCODE_CREDIT.getCode();
        } else {
            return crdFlg;
        }
    }

    //判断是否计入分润
    private boolean checkIsProfitFlag(PayTransaction payTransaction) {
        // 贷记卡且非押金交易才计入分润
        if (StringUtils.equalsAny(payTransaction.getCardFlag(),
                PayTransactionEnum.CardFlagEnum.ALIPAY.getCode(),
                PayTransactionEnum.CardFlagEnum.WECHAT.getCode(),
                PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode(),
                PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode(),
                PayTransactionEnum.CardFlagEnum.UNIONCODE_CREDIT.getCode()) &&
                !StringUtils.equals(payTransaction.getTransType(), LklTransTypeEnum.TYPE_412001.getTransType())) {
            return true;
        }
        return false;
    }
}